//
// Created by Zeppyrz on 2025/11/7.
//

#include "DownLoadTask.h"

#include <iostream>

namespace ZeDiskGUI {

using namespace ZeDisk;

void DownLoadTask::HandleMessage(const ZeDisk::Message *msg) {
  CommonTask::HandleMessage(msg);
  switch (msg->head.type) {
    case MSG_TYPE_DOWNLOAD_ACCEPT:
      HandleDownloadAccept(msg);
      is_recv_msg() = false;  // 不接收消息接受文件
      break;
    default:
      break;
  }
}

void DownLoadTask::HandleRawMessage(void *data, int size) {
  CommonTask::HandleRawMessage(data, size);
  if (!data || size < 0 || !outfile_.is_open()) {
    return;
  }
  outfile_.write(static_cast<char *>(data), size);
  download_size_ += size;

  if (download_size_ == file_size_) {
    if (download_complete_callback_) download_complete_callback_();
    std::cout << "[INFO] Client download file size: " << file_size_
              << " Success" << std::endl;
    outfile_.close();
    Message _msg;
    _msg.head.type = MSG_TYPE_DOWNLOAD_COMPLETE;
    _msg.head.size = 3;
    _msg.data = const_cast<char *>("OK");
    WriteMessage(&_msg);
  }
}

void DownLoadTask::ConnectCallback() {
  CommonTask::ConnectCallback();
  if (file_name_.empty()) {
    std::cout << "[ERROR] file path is empty " << std::endl;
    return;
  }

  // 发送下载文件请求
  Message _msg;
  _msg.head.type = MSG_TYPE_DOWNLOAD_INFO;
  _msg.head.size = file_name_.size();  // TODO: download filename
  _msg.data = const_cast<char *>(file_name_.c_str());
  WriteMessage(&_msg);
}

void DownLoadTask::HandleDownloadAccept(const ZeDisk::Message *msg) {
  // 1. 获取文件名和大小
  if (!msg->data || msg->head.size <= 0) return;
  std::string str(msg->data, msg->head.size);
  if (str.empty()) return;

  int pos = str.find(',');
  if (pos == std::string::npos) return;
  std::string filename = str.substr(0, pos);
  if (pos + 1 >= str.size()) return;
  std::string tmp = str.substr(pos + 1, str.size() - pos - 1);

  std::cout << "[INFO] Server Download file: " << filename << " size: " << tmp
            << std::endl;

  file_size_ = atoi(tmp.c_str());
  if (file_size_ <= 0) return;

  // 打开文件准备写入
  outfile_.open(local_file_path_.c_str(), std::ios::out | std::ios::binary);
  if (!outfile_.is_open()) {
    std::cout << "[ERROR] Failed to open file " << local_file_path_
              << std::endl;
    return;
  }
}

bool DownLoadTask::Stop() {
  if (outfile_.is_open()) outfile_.close();
  return CommonTask::Stop();
}

}  // namespace ZeDiskGUI